package com.interview.communication;

/**
 * 【方式1】wait/notify 方式
 * 最基础的线程通信机制，基于对象的监视器锁
 */
public class WaitNotifyExample {

    // 共享对象（作为锁）
    static class SharedData {
        private String message;
        private boolean hasData = false;

        // 生产数据
        synchronized void produce(String msg) {
            while (hasData) {
                try {
                    this.wait();  // 如果已有数据，生产者等待
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
            this.message = msg;
            this.hasData = true;
            System.out.println("【生产】" + msg);
            this.notifyAll();  // 唤醒所有等待线程
        }

        // 消费数据
        synchronized String consume() {
            while (!hasData) {
                try {
                    this.wait();  // 如果没有数据，消费者等待
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
            String msg = this.message;
            this.hasData = false;
            System.out.println("【消费】" + msg);
            this.notifyAll();  // 唤醒所有等待线程
            return msg;
        }
    }

    public static void demo() throws InterruptedException {
        SharedData data = new SharedData();

        // 生产者线程
        Thread producer = new Thread(() -> {
            for (int i = 1; i <= 3; i++) {
                data.produce("数据-" + i);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });

        // 消费者线程
        Thread consumer = new Thread(() -> {
            for (int i = 0; i < 3; i++) {
                data.consume();
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });

        producer.start();
        consumer.start();

        producer.join();
        consumer.join();
    }
}

